package cn.com.cfae.iras.doc.analyze.components;

import cn.com.cfae.iras.doc.analyze.components.common.UnitEnum;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by 佟媛媛 on 18/11/20.
 */
public class BaseCommon {

    private static Logger log = LoggerFactory.getLogger(BaseCommon.class);

    /**
     * @auth 佟媛媛
     * @date 18/11/20 下午4:32
     * @desc 单位穷举
     */
    public EnumMap<UnitEnum, Double> getEnumMap(String unit){
        EnumMap<UnitEnum, Double> rmbMap = new EnumMap(UnitEnum.class);
        UnitEnum rmb = getUnitEnum(unit);
        if(rmb==null){
            return rmbMap;
        }
        switch (rmb){
            case YUAN://元
                rmbMap.put(UnitEnum.YUAN,(double)1);
                rmbMap.put(UnitEnum.WANYUAN,(double)10000);
                rmbMap.put(UnitEnum.YIYUAN,(double)100000000);
                rmbMap.put(UnitEnum.WANYIYUAN,(double)1000000000000L);
                break;
            case WANYUAN://万元
                rmbMap.put(UnitEnum.YUAN,(double)1L/10000);
                rmbMap.put(UnitEnum.WANYUAN,(double)10000/10000);
                rmbMap.put(UnitEnum.YIYUAN,(double)100000000/10000);
                rmbMap.put(UnitEnum.WANYIYUAN,(double)1000000000000L/10000);
                break;
            case YIYUAN://亿元
                rmbMap.put(UnitEnum.YUAN,(double)1/100000000);
                rmbMap.put(UnitEnum.WANYUAN,(double)10000/100000000);
                rmbMap.put(UnitEnum.YIYUAN,(double)100000000/100000000);
                rmbMap.put(UnitEnum.WANYIYUAN,(double)1000000000000L/100000000);
                break;
            case WANYIYUAN://百亿元
                rmbMap.put(UnitEnum.YUAN,(double)1/1000000000000L);
                rmbMap.put(UnitEnum.WANYUAN,(double)10000/1000000000000L);
                rmbMap.put(UnitEnum.YIYUAN,(double)100000000/1000000000000L);
                rmbMap.put(UnitEnum.WANYIYUAN,(double)1000000000000L/1000000000000L);
                break;
            case DUN://顿
                rmbMap.put(UnitEnum.DUN,(double)1);
                rmbMap.put(UnitEnum.WANDUN,(double)10000);
                rmbMap.put(UnitEnum.YIDUN,(double)100000000);
                    break;
            case WANDUN://万吨
                rmbMap.put(UnitEnum.DUN,(double)1/10000);
                rmbMap.put(UnitEnum.WANDUN,(double)10000/10000);
                rmbMap.put(UnitEnum.YIDUN,(double)100000000/10000);
            break;
            case YIDUN://亿吨
                rmbMap.put(UnitEnum.DUN,(double)1/100000000);
                rmbMap.put(UnitEnum.WANDUN,(double)10000/100000000);
                rmbMap.put(UnitEnum.YIDUN,(double)100000000/100000000);
            break;
            case YUANDUN://元/吨
                rmbMap.put(UnitEnum.YUANDUN,(double)1);
                rmbMap.put(UnitEnum.WANYUANDUN,(double)10000);
            break;
            case WANYUANDUN://万元/顿
                rmbMap.put(UnitEnum.YUANDUN,(double)1/10000);
                rmbMap.put(UnitEnum.WANYUANDUN,(double)10000/10000);
            break;
            case PINGFANGMI://平方米
                rmbMap.put(UnitEnum.PINGFANGMI,(double)1);
                rmbMap.put(UnitEnum.WANPINGFANGMI,(double)10000);
                rmbMap.put(UnitEnum.BAIWANPINGFANGMI,(double)1000000);
            break;
            case WANPINGFANGMI://万平方米
                rmbMap.put(UnitEnum.PINGFANGMI,(double)1/10000);
                rmbMap.put(UnitEnum.WANPINGFANGMI,(double)10000/10000);
                rmbMap.put(UnitEnum.BAIWANPINGFANGMI,(double)1000000/10000);
            break;
            case BAIWANPINGFANGMI://百万平方米
                rmbMap.put(UnitEnum.PINGFANGMI,(double)1/1000000);
                rmbMap.put(UnitEnum.WANPINGFANGMI,(double)10000/1000000);
                rmbMap.put(UnitEnum.BAIWANPINGFANGMI,(double)1000000/1000000);
            break;
            case WA://瓦
                rmbMap.put(UnitEnum.WA,(double)1);
                rmbMap.put(UnitEnum.QIANWA,(double)1000);
                rmbMap.put(UnitEnum.WANQIANWA,(double)10000000);
                rmbMap.put(UnitEnum.YIQIANWAN,(double)100000000000L);
            break;
            case QIANWA://千瓦
                rmbMap.put(UnitEnum.WA,(double)1/1000);
                rmbMap.put(UnitEnum.QIANWA,(double)1000/1000);
                rmbMap.put(UnitEnum.WANQIANWA,(double)10000000/1000);
                rmbMap.put(UnitEnum.YIQIANWAN,(double)100000000000L/1000);
            break;
            case WANQIANWA://万千瓦
                rmbMap.put(UnitEnum.WA,(double)1/10000000);
                rmbMap.put(UnitEnum.QIANWA,(double)1000/10000000);
                rmbMap.put(UnitEnum.WANQIANWA,(double)10000000/10000000);
                rmbMap.put(UnitEnum.YIQIANWAN,(double)100000000000L/10000000);
                break;
            case YIQIANWAN://亿千瓦
                rmbMap.put(UnitEnum.WA,(double)1/100000000000L);
                rmbMap.put(UnitEnum.QIANWA,(double)1000/100000000000L);
                rmbMap.put(UnitEnum.WANQIANWA,(double)10000000/100000000000L);
                rmbMap.put(UnitEnum.YIQIANWAN,(double)100000000000L/100000000000L);
            break;
            case YUANQIANWASHI://元/千瓦时
                rmbMap.put(UnitEnum.YUANQIANWASHI,(double)1);
                rmbMap.put(UnitEnum.WANYUANQIANWASHI,(double)10000);
            break;
            case WANYUANQIANWASHI://万元/千瓦时
                rmbMap.put(UnitEnum.YUANQIANWASHI,(double)1/10000);
                rmbMap.put(UnitEnum.WANYUANQIANWASHI,(double)10000/10000);
            break;
            case REN://人
                rmbMap.put(UnitEnum.REN,(double)1);
                rmbMap.put(UnitEnum.WANREN,(double)10000);
                rmbMap.put(UnitEnum.YIREN,(double)100000000);
            break;
            case WANREN://万人
                rmbMap.put(UnitEnum.REN,(double)1/10000);
                rmbMap.put(UnitEnum.WANREN,(double)10000/10000);
                rmbMap.put(UnitEnum.YIREN,(double)100000000/10000);
            break;
            case YIREN://亿人
                rmbMap.put(UnitEnum.REN,(double)1/100000000);
                rmbMap.put(UnitEnum.WANREN,(double)10000/100000000);
                rmbMap.put(UnitEnum.YIREN,(double)100000000/100000000);
            break;
            case MI://米
                rmbMap.put(UnitEnum.MI,(double)1);
                rmbMap.put(UnitEnum.LI,(double)1/500);
                rmbMap.put(UnitEnum.GONGLI,(double)1/1000);
                rmbMap.put(UnitEnum.QIANMI,(double)1/1000);
                rmbMap.put(UnitEnum.KM,(double)1/1000);
                rmbMap.put(UnitEnum.WANGONGLI,(double)1/10000000);
            break;
            case LI://里
                rmbMap.put(UnitEnum.MI,(double)1*500);
                rmbMap.put(UnitEnum.LI,(double)1);
                rmbMap.put(UnitEnum.GONGLI,(double)1/2);
                rmbMap.put(UnitEnum.QIANMI,(double)1/2);
                rmbMap.put(UnitEnum.KM,(double)1/2);
                rmbMap.put(UnitEnum.WANGONGLI,(double)1/2*10000);
            break;
            case GONGLI://公里
            case QIANMI://千米
            case KM://KM
                rmbMap.put(UnitEnum.MI,(double)1*500*1000);
                rmbMap.put(UnitEnum.LI,(double)1/1000);
                rmbMap.put(UnitEnum.GONGLI,(double)1);
                rmbMap.put(UnitEnum.QIANMI,(double)1);
                rmbMap.put(UnitEnum.KM,(double)1);
                rmbMap.put(UnitEnum.WANGONGLI,(double)1/10000);
            break;
            case WANGONGLI://万公里
                rmbMap.put(UnitEnum.MI,(double)1/500*1000*10000);
                rmbMap.put(UnitEnum.LI,(double)10000*500);
                rmbMap.put(UnitEnum.GONGLI,(double)1/10000);
                rmbMap.put(UnitEnum.QIANMI,(double)1/10000);
                rmbMap.put(UnitEnum.KM,(double)1/10000);
                rmbMap.put(UnitEnum.WANGONGLI,(double)1);
            break;
            case YUANGONGLI://元/公里
                rmbMap.put(UnitEnum.YUANGONGLI,(double)1);
                rmbMap.put(UnitEnum.WANYUANGONGLI,(double)10000);
            break;
            case WANYUANGONGLI://万元/公里
                rmbMap.put(UnitEnum.YUANGONGLI,(double)1/10000);
                rmbMap.put(UnitEnum.WANYUANGONGLI,(double)10000/10000);
            break;
            case RENGONGLI://人公里
                rmbMap.put(UnitEnum.RENGONGLI,(double)1);
                rmbMap.put(UnitEnum.WANRENGONGLI,(double)10000);
                rmbMap.put(UnitEnum.BAIWANRENGONGLI,(double)100000000);
                rmbMap.put(UnitEnum.YIRENGONGLI,(double)1000000000000L);
                break;
            case WANRENGONGLI://万人公里
                rmbMap.put(UnitEnum.RENGONGLI,(double)1/10000);
                rmbMap.put(UnitEnum.WANRENGONGLI,(double)10000/10000);
                rmbMap.put(UnitEnum.BAIWANRENGONGLI,(double)100000000/10000);
                rmbMap.put(UnitEnum.YIRENGONGLI,(double)1000000000000L/10000);
            break;
            case BAIWANRENGONGLI://百万人公里
                rmbMap.put(UnitEnum.RENGONGLI,(double)1L/100000000);
                rmbMap.put(UnitEnum.WANRENGONGLI,(double)10000/100000000);
                rmbMap.put(UnitEnum.BAIWANRENGONGLI,(double)100000000/100000000);
                rmbMap.put(UnitEnum.YIRENGONGLI,(double)1000000000000L/100000000);
            break;
            case YIRENGONGLI://亿人公里
                rmbMap.put(UnitEnum.RENGONGLI,(double)1L/1000000000000L);
                rmbMap.put(UnitEnum.WANRENGONGLI,(double)10000/1000000000000L);
                rmbMap.put(UnitEnum.BAIWANRENGONGLI,(double)100000000/1000000000000L);
                rmbMap.put(UnitEnum.YIRENGONGLI,(double)1000000000000L/1000000000000L);
            break;
            case DUNGONGLI://吨公里
                rmbMap.put(UnitEnum.DUNGONGLI,(double)1L);
                rmbMap.put(UnitEnum.WANDUNGONGLI,(double)10000);
                rmbMap.put(UnitEnum.BAIWANDUNGONGLI,(double)100000000);
                rmbMap.put(UnitEnum.YIDUNGONGLI,(double)1000000000000L);
            break;
            case WANDUNGONGLI://万吨公里
                rmbMap.put(UnitEnum.DUNGONGLI,(double)1L/10000);
                rmbMap.put(UnitEnum.WANDUNGONGLI,(double)10000/10000);
                rmbMap.put(UnitEnum.BAIWANDUNGONGLI,(double)100000000/10000);
                rmbMap.put(UnitEnum.YIDUNGONGLI,(double)1000000000000L/10000);
            break;
            case BAIWANDUNGONGLI://百万吨公里
                rmbMap.put(UnitEnum.DUNGONGLI,(double)1L/100000000);
                rmbMap.put(UnitEnum.WANDUNGONGLI,(double)10000/100000000);
                rmbMap.put(UnitEnum.BAIWANDUNGONGLI,(double)100000000/100000000);
                rmbMap.put(UnitEnum.YIDUNGONGLI,(double)1000000000000L/100000000);
            break;
            case YIDUNGONGLI://亿吨公里
                rmbMap.put(UnitEnum.DUNGONGLI,(double)1L/1000000000000L);
                rmbMap.put(UnitEnum.WANDUNGONGLI,(double)10000/1000000000000L);
                rmbMap.put(UnitEnum.BAIWANDUNGONGLI,(double)100000000/1000000000000L);
                rmbMap.put(UnitEnum.YIDUNGONGLI,(double)1000000000000L/1000000000000L);
            break;
            case DUNREN://吨/人
                rmbMap.put(UnitEnum.DUNREN,(double)1L);
            break;
            case KEQIANWANSHI://克/千瓦时
                rmbMap.put(UnitEnum.KEQIANWANSHI,(double)1L);
            break;
        }
        return rmbMap;
    }

    /**
     * @auth 佟媛媛
     * @date 18/11/20 下午4:33
     * @desc 获取单位
     */
    private UnitEnum getUnitEnum(String unit){
        for(UnitEnum unitEnum : UnitEnum.values()){
            if(unitEnum.getName().equals(unit)){
                return unitEnum;
            }
        }
        return null;
    }

    /**
     * @auth 佟媛媛
     * @date 18/11/20 下午4:32
     * @desc 单位换算
     */
    public double getActualValue(String standardUnit,String actualUnit,double value){
        EnumMap<UnitEnum, Double> map = getEnumMap(standardUnit);
        if(MapUtils.isEmpty(map)){
            return Double.MAX_VALUE;
        }
        for(Map.Entry<UnitEnum, Double>  entry: map.entrySet()){
            if(entry.getKey().getName().equals(actualUnit)){
                return getTwoDecimal(value*entry.getValue());
            }
        }
        return Double.MAX_VALUE;
    }

    /**
     * @auth 佟媛媛
     * @date 18/12/6 下午5:21
     * @desc 近一期
     */
    public String getJYQ(Map map){
        if(MapUtils.isEmpty(map)){
            return "";
        }
        List<Integer> yearList = new ArrayList<>();
        for(Object key:map.keySet()){
            yearList.add(Integer.parseInt((String)key));
        }
        Collections.sort(yearList,Collections.reverseOrder());
        return yearList.get(0)+"";
    }

    /**
     * @auth 佟媛媛
     * @date 18/12/6 下午5:21
     * @desc 近一年
     */
    public String getJYN(Map map){
        if(MapUtils.isEmpty(map)){
            return "";
        }
        List<Integer> yearList = new ArrayList<>();
        for(Object key:map.keySet()){
            yearList.add(Integer.parseInt((String)key));
        }
        Collections.sort(yearList,Collections.reverseOrder());
        if(yearList.size()<2){
            return "";
        }
        return yearList.get(1)+"";
    }

    /**
     * @auth 佟媛媛
     * @date 18/12/10 下午4:41
     * @desc 获取三年及一期
     */
    public String[] getSNJYQ(Map map){
        if(MapUtils.isEmpty(map)){
            return null;
        }
        List<Integer> yearList = new ArrayList<>();
        for(Object key:map.keySet()){
            yearList.add(Integer.parseInt((String)key));
        }
        Collections.sort(yearList,Collections.reverseOrder());
        String[] years = new String[yearList.size()];
        for(int i=0;i<yearList.size();i++){
            years[i] = yearList.get(i)+"";
        }
        return years;
    }

    /**
     * @auth 佟媛媛
     * @date 18/11/1 下午7:26
     * @desc 获取近一期
     */
    public String getJYQ(){
        Calendar cal= Calendar.getInstance();
        int y=cal.get(Calendar.YEAR);
        cal.add(Calendar.YEAR,-1);
        int y1=cal.get(Calendar.YEAR);
        String year = y1+"12";
        try{
            Date today = new Date();
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            Date date1031 = format.parse(y+"-10-31");
            Date date0831 = format.parse(y+"-08-31");
            Date date0430 = format.parse(y+"-04-30");
            if(today.getTime()-date1031.getTime()>0){//10.31以后
                year = y+"09";
            }else if(today.getTime()-date0831.getTime()>0){//08.31以后
                year = y+"06";
            }else if(today.getTime()-date0430.getTime()>0){//04.30以后
                year = y+"03";
            }else{
                year = y1+"12";
            }
        }catch (Exception e){
            log.error(e.getMessage(),e);
        }
        return year;
    }

    /**
     * @auth 佟媛媛
     * @date 18/11/20 上午10:11
     * @desc 近一年
     */
    public String getJYN(){
        Calendar cal= Calendar.getInstance();
        cal.add(Calendar.YEAR,-1);
        int y1=cal.get(Calendar.YEAR);
        String year = y1+"12";
        return year;
    }

    /**
     * @auth 佟媛媛
     * @date 18/11/1 下午7:26
     * @desc 获取三年及一期
     */
    public String[] getSNJYQ(){
        Calendar cal = Calendar.getInstance();
        int y = cal.get(Calendar.YEAR);
        cal.add(Calendar.YEAR,-1);
        int y1 = cal.get(Calendar.YEAR);
        cal.add(Calendar.YEAR,-1);
        int y2 = cal.get(Calendar.YEAR);
        cal.add(Calendar.YEAR,-1);
        int y3 = cal.get(Calendar.YEAR);
        cal.add(Calendar.YEAR,-1);
        int y4 = cal.get(Calendar.YEAR);
        String[] years = new String[]{y4+"12",y3+"12",y2+"12",y1+"12"};
        try{
            Date today = new Date();
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            Date date1031 = format.parse(y+"-10-31");
            Date date0831 = format.parse(y+"-08-31");
            Date date0430 = format.parse(y+"-04-30");
            if(today.getTime()-date1031.getTime()>0){//10.31以后
                years = new String[]{y3+"12",y2+"12",y1+"12",y+"09"};
            }else if(today.getTime()-date0831.getTime()>0){//08.31以后
                years = new String[]{y3+"12",y2+"12",y1+"12",y+"06"};
            }else if(today.getTime()-date0430.getTime()>0){//04.30以后
                years = new String[]{y3+"12",y2+"12",y1+"12",y+"03"};
            }else{
                years = new String[]{y4+"12",y3+"12",y2+"12",y1+"12"};
            }
        }catch (Exception e){
            log.error(e.getMessage(),e);
        }
        return years;
    }

    /**
     * @auth 佟媛媛
     * @date 18/11/20 下午4:33
     * @desc 获取数字
     */
    public double getDouble(String value){
        if(StringUtils.isEmpty(value)){
            return 0;
        }
        String rs = null;
        Pattern p1 = Pattern.compile("[+|-]{0,1}((\\d{0,3}),)+((\\d{0,3}).)?\\d+");
        Pattern p2 = Pattern.compile("[+|-]{0,1}((\\d+).)+\\d+");
        Pattern p3 = Pattern.compile("[+|-]{0,1}\\d+");
        Matcher m1 = p1.matcher(value);
        if(m1.find()){
            rs = m1.group();
        }else{
            Matcher m2 = p2.matcher(value);
            if(m2.find()){
                rs = m2.group();
            }else{
                Matcher m3 = p3.matcher(value);
                if(m3.find()){
                    rs = m3.group();
                }else{
                    log.error("转换double失败，原值：{}",value);
                }
            }
        }
        if(StringUtils.isNotEmpty(rs)){
            double d = Double.valueOf(rs.replace(",",""));
            log.info("getDouble {} , {}",value,d);
            return d;
        }
        return 0;
    }

    public String doubleToBigDecimal(double d){
        BigDecimal rs = new BigDecimal(String.valueOf(d));
        return rs.toString();
    }

    /**
     * @auth 佟媛媛
     * @date 18/11/20 下午4:33
     * @desc 获取单位
     */
    public String getUnit(String value){
        if(StringUtils.isEmpty(value)){
            return null;
        }
        String rs = null;
        Pattern p1 = Pattern.compile("[+|-]{0,1}((\\d{0,3}),)+((\\d{0,3}).)?\\d+");
        Pattern p2 = Pattern.compile("[+|-]{0,1}((\\d+).)+\\d+");
        Pattern p3 = Pattern.compile("[+|-]{0,1}\\d+");
        Matcher m1 = p1.matcher(value);
        if(m1.find()){
            rs = m1.group();
        }else{
            Matcher m2 = p2.matcher(value);
            if(m2.find()){
                rs = m2.group();
            }else{
                Matcher m3 = p3.matcher(value);
                if(m3.find()){
                    rs = m3.group();
                }else{
                    log.error("获取单位失败，原值：{}",value);
                }
            }
        }
        if(StringUtils.isNotEmpty(rs)){
            String d = value.replace(rs,"").replace(" ","");
            log.info("getUnit {} , {}",value,d);
            return d;
        }
        return null;
    }

    /**
     * @auth 佟媛媛
     * @date 18/11/20 下午4:34
     * @desc 判断是否在区间
     */
    public boolean isRange(String v){
        if(StringUtils.isEmpty(v)){
            return false;
        }
        v = v.replace(" ","").trim();
        String numPattern = "^(\\[|\\()?(\\+∞|\\-∞){0,1}\\d*.{0,1}\\d*,{1}\\d*.{0,1}\\d*(\\+∞|\\-∞){0,1}(\\]|\\))$";
        return Pattern.matches(numPattern, v);
    }

    public boolean isNum(String v){
        String numPattern = "^(\\-|\\+)?\\d+(,\\d{3})*(\\.\\d+)?([Ee][+-]?[0-9]{0,2})?$";
        return Pattern.matches(numPattern, v);
    }

    /**
     * 将数据保留两位小数
     */
    public double getTwoDecimal(double num) {
        DecimalFormat dFormat = new DecimalFormat("#.0000");
        String yearString = dFormat.format(num);
        Double temp = Double.valueOf(yearString);
        return temp;
    }

    /**
     * @auth 佟媛媛
     * @date 18/11/26 下午4:12
     * @desc 去除特殊字符
     */
    public String stringFilter(String str) {
        try{
            // 清除掉所有特殊字符
            String regEx="[`~!@#$^&*()=|{}':;',\\[\\]<>/?~！@#￥……&*（）－|{}【】‘；：”“’\"。，、？．]";
            Pattern p = Pattern.compile(regEx);
            Matcher m = p.matcher(str);
            return m.replaceAll("").trim();
        }catch (Exception e){
            log.error(e.getMessage(),e);
        }
        return str;
    }
}
